/*
 * @Author: yangzonglong
 * @Date: 2021-02-22 13:56:10
 * @version: v1.0.0
 * @Descripttion: 
 * @LastEditors: yangzonglong
 * @LastEditTime: 2021-06-30 14:25:13
 * @Auditor: 
 */
import React, { useCallback, useState } from 'react';
import { Icon } from '@library';
import update from 'immutability-helper';
import classNames from 'classnames';
// import ModalForm from './_modalForm';
// import ModalTable from './_modalTable';
import useFdStore from './../../../hooks/useFdStore';
import { ActionTypes } from './../../../reducer';
import { menus } from './../../../config';
import { MenuProps, ControlProps, DragSourceProps } from './../../../interface';
import MenuItem from './MenuItem';
import { createControlDefOptions, controlToTree, flatControl } from './../../../util';
import { ControlType } from '../../../config';
import style from './../../design.module.scss';

const typeMap = {
  date: ControlType.DATE_PICKER,
  string: ControlType.INPUT,
  boolean: ControlType.SWITCH,
  array: ControlType.TABLE,
  number: ControlType.INPUT_NUMBER,
};

const Menu = () => {

  const { dispatch, state: { list, hoverControlId, hideMenus, modelListAndModelName } } = useFdStore();

  const [visible, setVisible] = useState(false);
  const [tableVisible, setTableVisible] = useState(false);

  const addControl = useCallback((item: MenuProps) => {
    if (item.type === 'modelform') return setVisible(true);
    if (item.type === 'modeltable') return setTableVisible(true);

    if (hoverControlId) {
      const index = list.findIndex(item => item.id === hoverControlId);
      list.splice(index, 0, createControlDefOptions(item.type));
      dispatch({
        type: ActionTypes.SYNC_LIST,
        list: list,
        modelListAndModelName,
        hoverControlId: '',
        dragDirection: '',
        dragSource: ''
      });

    } else {
      dispatch({
        type: ActionTypes.SYNC_LIST,
        modelListAndModelName,
        list: list.concat(createControlDefOptions(item.type))
      });
    }

  }, [dispatch, hoverControlId, modelListAndModelName, list]);

  const appendControl = useCallback((item: MenuProps, parent: ControlProps) => {
    if (item.type === 'modelform') return setVisible(true);
    if (item.type === 'modeltable') return setTableVisible(true);
    // 插入子组件
    if (parent && (parent.type === ControlType.ROW || parent.type === ControlType.COL || parent.type === ControlType.COLLAPSE)) {
      const control = createControlDefOptions(item.type);
      control.parentId = parent.id;

      const handList = flatControl(list);

      dispatch({
        type: ActionTypes.SYNC_LIST,
        modelListAndModelName,
        list: controlToTree(handList.concat(control))
      });
      return;
    }

    if (hoverControlId) {
      const index = list.findIndex(item => item.id === hoverControlId);

      dispatch({
        type: ActionTypes.SYNC_LIST,
        modelListAndModelName,
        list: update(list, {
          $splice: [[index, 0, createControlDefOptions(item.type)]]
        }),
        hoverControlId: '',
        dragDirection: '',
        dragSource: ''
      });

    } else {
      dispatch({
        type: ActionTypes.SYNC_LIST,
        modelListAndModelName,
        list: update(list, {
          $push: [createControlDefOptions(item.type)]
        })
      });
    }
  }, [dispatch, hoverControlId, modelListAndModelName, list]);

  const setDragSource = useCallback((dragSource: DragSourceProps) => {
    dispatch({ dragSource });
  }, [dispatch]);

  const shrink = () => {
    dispatch({
      type: ActionTypes.TOGGLE_MENUS,
      hideMenus: true
    });
  };

  const show = () => {
    dispatch({
      type: ActionTypes.TOGGLE_MENUS,
      hideMenus: false
    });
  };

  const onOk = (rows: any[]) => {
    setVisible(false);
    const _list: any[] = [];
    rows.forEach(item => {
      typeMap[item.type] && _list.push(createControlDefOptions(typeMap[item.type], { name: item.filedCode, label: item.name }));
    });

    dispatch({
      type: ActionTypes.SYNC_LIST,
      modelListAndModelName,
      list: update(list, {
        $push: _list
      })
    });
  };

  const onTableOk = (options: any, value: string) => {
    setTableVisible(false);
    dispatch({
      type: ActionTypes.SYNC_LIST,
      modelListAndModelName: value,
      list: update(list, {
        $push: [options]
      })
    });
  };

  const onErr = () => setTableVisible(false);

  return (
    <div className={classNames(style.menus, hideMenus ? style.hidemenus : '')}>
      {
        hideMenus ? <Icon onClick={show} icon="&#xe649;" className={style.shrink} /> : <Icon className={style.shrink} onClick={shrink} icon="&#xe64a;" />
      }
      {
        !hideMenus && menus.map((group, groupIndex) => (
          <dl key={groupIndex}>
            <dt>{group.title}</dt>
            <dd>
              {group.children.map((item, index) => (
                <MenuItem
                  appendControl={appendControl}
                  addControl={addControl}
                  key={index}
                  setDragSource={setDragSource}
                  item={item} />
              ))}
            </dd>
          </dl>
        ))
      }

      {/* <ModalForm visible={visible} onCancel={() => setVisible(false)} onOk={onOk} />
      <ModalTable visible={tableVisible} onCancel={() => setTableVisible(false)} onOk={onTableOk} onErr={onErr} /> */}
    </div>
  );
};

export default Menu;